﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Vowei.Core.Models;
using Vowei.Data.Converters.Excel;
using Vowei.Data.Helpers;
using Vowei.Data.Models;
using Vowei.Web.Helpers;
using Vowei.Web.Models;
using Vowei.Web.Security;

namespace Vowei.Web.Controllers
{
    public class AccountController : G18nController
    {
        public IFormsAuthenticationService FormsService { get; set; }

        public IMembershipService MembershipService { get; set; }

        private IVoweiContext _context;
        private IUser _user;

        public AccountController(IVoweiContext context, IUser user)
        {
            _context = context;
            _user = user;
        }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }

        [Authorize]
        public ActionResult Index()
        {
            return View(_context.Employees.Query.AsEnumerable());
        }

        public ActionResult LogIn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogIn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var service = MembershipService;

                // TODO: 研究针对google帐号的支持
                if (model.LogOnChannel == LogOnChannel.GoogleTalk)
                    throw new NotImplementedException(T("对Google帐号的支持尚未实现，请使用其他方式登陆系统！"));
                else if (model.LogOnChannel == LogOnChannel.MicrosoftLive)
                    service = LiveMembershipSerive.SingletonInstance;

                if (service.ValidateUser(model.Email, model.Password))
                {
                    FormsService.SignIn(model.Email, model.RememberMe);
                    if (!String.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    // ModelState.AddModelError("", T("The user name or password provided is incorrect."));
                    ModelState.AddModelError("", T("用户名或者密码错误！"));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult LogOff()
        {
            FormsService.SignOut();

            return RedirectToAction("Index", "Home");
        }

        public ActionResult Register()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus = MembershipService.CreateUser(model.Email, model.Password, model.Email);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    FormsService.SignIn(model.Email, false /* createPersistentCookie */);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    // ModelState.AddModelError("", T("The current password is incorrect or the new password is invalid."));
                    ModelState.AddModelError("", T("老密码输入错误或者是新密码不合乎安全密码规则！"));
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        [Authorize]
        public ActionResult ImportUsers(Guid? pid)
        {
            if (pid.HasValue)
            {
                ViewData["ProjectId"] = pid.Value;
            }
            else
            {
                ViewData["Projects"] = ViewHelpers.SerializeToJson(_context.Projects.Query.My(_user));
            }

            return View();
        }

        [Authorize]
        [HttpPost]
        public ActionResult ConfirmImport()
        {
            // TODO: 可以考虑创建一个通用的多步导入Excel文件的类型
            var users = Session["ImportUsers_Users"] as IEnumerable<ResourceAssignmentDetail>;
            var pid = (Guid)Session["ImportUsers_Pid"];

            try
            {
                ImportUsersImpl(users, pid);
            }
            finally
            {
                Session.Remove("ImportUsers_Users");
            }

            return RedirectToAction("Details", "Project", new { id = pid });
        }

        public void ImportUsersImpl(IEnumerable<ResourceAssignmentDetail> assignments, Guid pid)
        {
            var ras = new List<ResourceAssignment>();
            var employees = new List<Employee>();
            foreach (var ad in assignments)
            {
                if (!string.IsNullOrEmpty(ad.Employee.Email))
                    AddMembership(ad.Employee.Email);

                Debug.Assert(ad.Assignment.ResourceId == ad.Employee.ID);
                ras.Add(ad.Assignment);
                employees.Add(ad.Employee);
            }

            var project = _context.Projects.Include("ResourceAssignments").Query.First(p => p.ID == pid);

            ImportHelper.ImportAssignmentTo(project, _context, ras, employees, Translator);

            project.TrackingChange(
                string.Format(T("用户从Excel文件里向项目{0}导入了项目组成员!"),
                project.Title), _user);
        }

        [Authorize]
        [HttpPost]
        public ActionResult ImportUsers(FormCollection collection)
        {
            var stream = Request.Files["UsersSpreadsheet"].InputStream;
            var filename = Request.Files["UsersSpreadsheet"].FileName;
            var pid = Guid.Parse(collection["Project"]);
            var isXlsx = string.Compare(
                Path.GetExtension(filename), ".xlsx", true) == 0;

            if (isXlsx)
                throw new NotSupportedException(T("暂时还不支持Excel 2007的XLSX格式，请上传Excel 2003格式的文件！"));

            var uce = new UserExcelConverter();
            var converter = new AssignmentExcelConverter(uce);

            var users = converter.ConvertFrom(stream);
            Session["ImportUsers_Users"] = users;
            Session["ImportUsers_Pid"] = pid;

            return View("ConfirmImport", users);
        }

        [Authorize]
        public ActionResult ViewUsers(Guid pid)
        {
            var project = _context.Projects.Include("ResourceAssignments").Query.Single(p => p.ID == pid);
            if (project == null)
                throw new InvalidOperationException(string.Format(T("找不到ID为{0}的项目!"), pid));

            return View(project);
        }

        [Authorize]
        public ActionResult AddUserTo(Guid pid)
        {
            var project = _context.Projects.Find(pid);
            return View(project);
        }

        [Authorize]
        [HttpPost]
        public ActionResult AddUserTo(FormCollection collection)
        {
            var pidStr = collection["ProjectId"];
            var userNameStr = collection["UserEmails"];
            var pid = Guid.Parse(pidStr);
            var userNames = EditingHelpers.SplitUsers(userNameStr);

            foreach (var userName in userNames)
                AddMembership(userName);

            var project = _context.Projects.Include("ResourceAssignments").Query.First(p => p.ID == pid);

            foreach (var userName in userNames)
            {
                if (EntityHelpers.MatchUserEmail(userName))
                    ImportHelper.AssignMemberTo(project, _context, new Employee { Email = userName }, Translator);
                else
                    throw new NotSupportedException(string.Format(T("不支持类似[{0}]格式的用户名，请输入合法的电子邮件地址！"), userName));
            }

            _context.SaveChanges();

            return RedirectToAction("Details", "Project", new { id = pid });
        }

        //private void AssignMemberTo(Project project, Employee user, IVoweiContext context)
        //{
        //    if (!project.ResourceAssignments.Any(t => t.User == user.Email))
        //    {
        //        project.ResourceAssignments.Add(new ResourceAssignment()
        //        {
        //            ProjectId = project.ID,
        //            User = user.Email
        //        });
        //    }
        //    else
        //    {
        //        Trace.TraceWarning(string.Format(T("用户{0}已经存在于项目组{1}中了!"), user.Email, project.Title));
        //    }

        //    if (!context.Employees.Query.Any(e => e.Email == user.Email))
        //    {
        //        context.Employees.Add(user);
        //    }
        //    else
        //    {
        //        Trace.TraceInformation(string.Format(T("用户[{0}]已经存在于数据库当中了！"), user.Email));
        //    }
        //}

        private void AddMembership(string username)
        {
            //if (Membership.GetUserNameByEmail(username) == null)
            //{
            //    MembershipCreateStatus status;
            //    Membership.CreateUser(username,
            //        username,
            //        username,
            //        "",
            //        "",
            //        true,
            //        out status);

            //    if (status != MembershipCreateStatus.Success)
            //        Trace.TraceError(string.Format("创建用户[{0}]的时候发生错误，具体错误信息是：{1}。", username, status));
            //}
        }

        public ActionResult Details(string id)
        {
            var employee = _context.Employees.Query.Single(e => e.Email == id);
            return View(employee);
        }

        public ActionResult ApplyVacation()
        {
            return View();
        }

        //[HttpPost]
        //public ActionResult ApplyVacation(Vacation vacation)
        //{
        //    var email = _user.Email;
        //    var uname = _user.UserName;
        //    var employee = _context.Employees.Query.Single(e => e.Email == email || e.UserName == uname);
        //    var eid = employee.ID;
        //    var assignments = _context.Assignments.Include("WorkCalendar").Query.Where(a => a.ResourceId == eid);

        //    foreach (var assignment in assignments)
        //    {
        //        assignment.WorkCalendar = assignment.WorkCalendar.Except(new ExceptionPeriod
        //        {
        //            Description = vacation.Description,
        //            Start = vacation.Start,
        //            Finish = vacation.Finish,
        //            Name = string.Format(T("员工 [{0}] 的请假申请！"), _user.GetIdentifier()),
        //            Type = WorkingTimeType.Nonworking
        //        });
        //    }

        //    _context.SaveChanges();
        //    return View();
        //}
    }
}